﻿(function ($) {
    $.fn.swapClass = function (c1, c2) {
        return this.removeClass(c1).addClass(c2);
    };
    $.fn.switchClass = function (c1, c2) {
        if (this.hasClass(c1)) {
            return this.swapClass(c1, c2);
        }
        else {
            return this.swapClass(c2, c1);
        }
    };
    $.fn.treeview = function (settings) {
        var dfop =
            {
                method: "POST", //默认采用POST提交数据
                datatype: "json", //数据类型是json
                url: false, //异步请求的url
                cbiconpath: "../../images/tree/", //checkbox icon的目录位置
                icons: ["checkbox_0.gif", "checkbox_1.gif", "checkbox_2.gif"],
                emptyiconpath: "../../images/s.gif", //checkbxo三态的图片
                showcheck: false, //是否显示checkbox
                oncheckboxclick: false, //当checkstate状态变化时所触发的事件，但是不会触发因级联选择而引起的变化
                onnodeclick: false, // 触发节点单击事件
                cascadecheck: true, //是否启用级联，默认启用
                data: null, //初始化数据
                clicktoggle: true, //点击节点展开和收缩子节点
                theme: "bbit-tree-arrows" //三种风格备选：bbit-tree-lines ,bbit-tree-no-lines,bbit-tree-arrows
            };
        $.extend(dfop, settings); //用传进来的参数覆盖默认，没传则保留
        var treenodes = dfop.data;
        var me = $(this);
        var id = me.attr("id");
        if (id == null || id == "") {
            id = "bbtree" + (+new Date);
            me.attr("id", id);
        }
        var html = [];
        buildtree(dfop.data, html);
        me.addClass("bbit-tree").html(html.join(""));
        InitEvent(me);
        html = null;
        //预加载图片
        if (dfop.showcheck) {
            for (var i = 0; i < 3; i++) {
                var im = new Image();
                im.src = dfop.cbiconpath + dfop.icons[i];
            }
        }
        //region
        function buildtree(data, ht) {
            ht.push("<div class='bbit-tree-bwrap'>");
            ht.push("<div class='bbit-tree-body'>");
            ht.push("<ul class='bbit-tree-root ", dfop.theme, "'>");
            if (data && data.length > 0) {
                var l = data.length;
                for (var i = 0; i < l; i++) {
                    buildnode(data[i], ht, 0, i, i == l - 1);
                }
            }
            else {
                asnyloadc(null, false, function (data) {
                    if (data && data.length > 0) {
                        treenodes = data;
                        dfop.data = data;
                        var l = data.length;
                        for (var i = 0; i < l; i++) {
                            buildnode(data[i], ht, 0, i, i == l - 1);
                        }
                    }
                });
            }
            ht.push("</ul>");
            ht.push("</div>");
            ht.push("</div>");
        }
        //endregion
        function buildnode(nd, ht, deep, path, isend) {
            var nid = nd.id.replace(/[^\w]/gi, "_");
            ht.push("<li class='bbit-tree-node'>");
            ht.push("<div id='", id, "_", nid, "' tpath='", path, "' unselectable='on' title='", nd.text, "'");
            var cs = [];
            cs.push("bbit-tree-node-el");
            if (nd.hasChildren) {
                cs.push(nd.isexpand ? "bbit-tree-node-expanded" : "bbit-tree-node-collapsed");
            }
            else {
                cs.push("bbit-tree-node-leaf");
            }
            if (nd.classes) {
                cs.push(nd.classes);
            }
            ht.push(" class='", cs.join(" "), "'>");
            ht.push("<span class='bbit-tree-node-indent'>");
            if (deep == 1) {
                ht.push("<img class='bbit-tree-icon' src='", dfop.emptyiconpath, "'/>");
            }
            else if (deep > 1) {
                ht.push("<img class='bbit-tree-icon' src='", dfop.emptyiconpath, "'/>");
                for (var j = 1; j < deep; j++) {
                    ht.push("<img class='bbit-tree-elbow-line' src='", dfop.emptyiconpath, "'/>");
                }
            }
            ht.push("</span>");
            cs.length = 0;
            if (nd.hasChildren) {
                if (nd.isexpand) {
                    cs.push(isend ? "bbit-tree-elbow-end-minus" : "bbit-tree-elbow-minus");
                }
                else { cs.push(isend ? "bbit-tree-elbow-end-plus" : "bbit-tree-elbow-plus"); }
            }
            else {
                cs.push(isend ? "bbit-tree-elbow-end" : "bbit-tree-elbow");
            }
            ht.push("<img class='bbit-tree-ec-icon ", cs.join(" "), "' src='", dfop.emptyiconpath, "'/>");
            ht.push("<img class='bbit-tree-node-icon' src='", dfop.emptyiconpath, "'/>");
            if (dfop.showcheck && nd.showcheck) {
                if (nd.checkstate == null || nd.checkstate == undefined) {
                    nd.checkstate = 0;
                }
                ht.push("<img  id='", id, "_", nid, "_cb' class='bbit-tree-node-cb' src='", dfop.cbiconpath, dfop.icons[nd.checkstate], "'/>");
            }
            if (nd.href) {
                ht.push("<a hideFocus class='bbit-tree-node-anchor' tabIndex=1 href='" + nd.href + "'>");
            }
            else {
                ht.push("<a hideFocus class='bbit-tree-node-anchor' tabIndex=1 href='javascript:void(0);'>");
            }
            if (nd.isdelete) {
                ht.push("<span unselectable='on' style='color:red'>" + nd.text + "(" + nd.deletetext + ")</span>");
            }
            else {
                ht.push("<span unselectable='on'>" + nd.text + "</span>");
            }
            ht.push("</a>");
            ht.push("</div>");
            if (nd.hasChildren) {
                if (nd.isexpand) {
                    ht.push("<ul  class='bbit-tree-node-ct'  style='z-index: 0; position: static; visibility: visible; top: auto; left: auto;'>");
                    if (nd.ChildNodes) {
                        var l = nd.ChildNodes.length;
                        for (var k = 0; k < l; k++) {
                            nd.ChildNodes[k].parent = nd;
                            buildnode(nd.ChildNodes[k], ht, deep + 1, path + "." + k, k == l - 1);
                        }
                    }
                    ht.push("</ul>");
                }
                else {
                    ht.push("<ul style='display:none;'></ul>");
                }
            }
            ht.push("</li>");
            nd.render = true;
        }
        function getItem(path) { var ap = path.split("."); var t = treenodes; for (var i = 0; i < ap.length; i++) { if (i == 0) { t = t[ap[i]]; } else { t = t.ChildNodes[ap[i]]; } } return t; }
        function check(item, state, type) {
            var pstate = item.checkstate; if (type == 1) { item.checkstate = state; } else { var cs = item.ChildNodes; var l = cs.length; var ch = true; for (var i = 0; i < l; i++) { if ((state == 1 && cs[i].checkstate != 1) || state == 0 && cs[i].checkstate != 0) { ch = false; break; } } if (ch) { item.checkstate = state; } else { item.checkstate = 2; } }
            //change show
            if (item.render && pstate != item.checkstate) { var nid = item.id.replace(/[^\w]/gi, "_"); var et = $("#" + id + "_" + nid + "_cb"); if (et.length == 1) { et.attr("src", dfop.cbiconpath + dfop.icons[item.checkstate]); } }
        }
        //遍历子节点
        function cascade(fn, item, args) { if (fn(item, args, 1) != false) { if (item.ChildNodes != null && item.ChildNodes.length > 0) { var cs = item.ChildNodes; for (var i = 0, len = cs.length; i < len; i++) { cascade(fn, cs[i], args); } } } }
        //冒泡的祖先
        function bubble(fn, item, args) { var p = item.parent; while (p) { if (fn(p, args, 0) === false) { break; } p = p.parent; } }
        function nodeclick(e) {
            var path = $(this).attr("tpath"); var et = e.target || e.srcElement; var item = getItem(path);
            if (et.tagName == "IMG") {
                if ($(et).hasClass("bbit-tree-elbow-plus") || $(et).hasClass("bbit-tree-elbow-end-plus")) { var ul = $(this).next(); if (ul.hasClass("bbit-tree-node-ct")) { ul.show(); } else { var deep = path.split(".").length; if (item.complete) { item.ChildNodes != null && asnybuild(item.ChildNodes, deep, path, ul, item); } else { $(this).addClass("bbit-tree-node-loading"); asnyloadc(item, true, function (data) { item.complete = true; item.ChildNodes = data; asnybuild(data, deep, path, ul, item); }); } } if ($(et).hasClass("bbit-tree-elbow-plus")) { $(et).swapClass("bbit-tree-elbow-plus", "bbit-tree-elbow-minus"); } else { $(et).swapClass("bbit-tree-elbow-end-plus", "bbit-tree-elbow-end-minus"); } $(this).swapClass("bbit-tree-node-collapsed", "bbit-tree-node-expanded"); }
                else if ($(et).hasClass("bbit-tree-elbow-minus") || $(et).hasClass("bbit-tree-elbow-end-minus")) {  //- 号需要收缩
                    $(this).next().hide(); if ($(et).hasClass("bbit-tree-elbow-minus")) { $(et).swapClass("bbit-tree-elbow-minus", "bbit-tree-elbow-plus"); } else { $(et).swapClass("bbit-tree-elbow-end-minus", "bbit-tree-elbow-end-plus"); } $(this).swapClass("bbit-tree-node-expanded", "bbit-tree-node-collapsed");
                } else if ($(et).hasClass("bbit-tree-node-cb")) { var s = item.checkstate != 1 ? 1 : 0; var r = true; if (dfop.oncheckboxclick) { r = dfop.oncheckboxclick.call(et, item, s); } if (r != false) { if (dfop.cascadecheck) { cascade(check, item, s); bubble(check, item, s); } else { check(item, s, 1); } } }
            } else { if (dfop.citem) { var nid = dfop.citem.id.replace(/[^\w]/gi, "_"); $("#" + id + "_" + nid).removeClass("bbit-tree-selected"); } dfop.citem = item; $(this).addClass("bbit-tree-selected"); if (dfop.onnodeclick) { if (!item.expand) { item.expand = function () { expandnode.call(item); }; } dfop.onnodeclick.call(this, item); } }
        }
        function expandnode() { var item = this; var nid = item.id.replace(/[^\w]/gi, "_"); var img = $("#" + id + "_" + nid + " img.bbit-tree-ec-icon"); if (img.length > 0) { img.click(); } }
        function asnybuild(nodes, deep, path, ul, pnode) { var l = nodes.length; if (l > 0) { var ht = []; for (var i = 0; i < l; i++) { nodes[i].parent = pnode; buildnode(nodes[i], ht, deep, path + "." + i, i == l - 1); } ul.html(ht.join("")); ht = null; InitEvent(ul); } ul.addClass("bbit-tree-node-ct").css({ "z-index": 0, position: "static", visibility: "visible", top: "auto", left: "auto", display: "" }); ul.prev().removeClass("bbit-tree-node-loading"); }
        function asnyloadc(pnode, isAsync, callback) {
            if (dfop.url) {
                if (pnode && pnode != null)
                    var param = builparam(pnode);
                $.ajax({
                    type: dfop.method,
                    url: dfop.url,
                    data: param,
                    async: isAsync,
                    dataType: dfop.datatype,
                    success: callback,
                    error: function (e) { alert("error occur!"); }
                });
            }
        }
        function builparam(node) {
            var p = [{ name: "id", value: encodeURIComponent(node.id) }
                    , { name: "text", value: encodeURIComponent(node.text) }
                    , { name: "value", value: encodeURIComponent(node.value) }
                    , { name: "checkstate", value: node.checkstate}];
            return p;
        }
        function bindevent() { $(this).hover(function () { $(this).addClass("bbit-tree-node-over"); }, function () { $(this).removeClass("bbit-tree-node-over"); }).click(nodeclick).find("img.bbit-tree-ec-icon").each(function (e) { if (!$(this).hasClass("bbit-tree-elbow")) { $(this).hover(function () { $(this).parent().addClass("bbit-tree-ec-over"); }, function () { $(this).parent().removeClass("bbit-tree-ec-over"); }); } }); }
        function InitEvent(parent) { var nodes = $("li.bbit-tree-node>div", parent); nodes.each(bindevent); }
        function reflash(itemId) {
            var nid = itemId.replace(/[^\w-]/gi, "_"); var node = $("#" + id + "_" + nid);
            if (node.length > 0) {
                node.addClass("bbit-tree-node-loading");
                var isend = node.hasClass("bbit-tree-elbow-end") || node.hasClass("bbit-tree-elbow-end-plus") || node.hasClass("bbit-tree-elbow-end-minus");
                var path = node.attr("tpath");
                var deep = path.split(".").length;
                var item = getItem(path);
                if (item) {
                    asnyloadc(item, true, function (data) {
                        item.complete = true;
                        item.ChildNodes = data;
                        item.isexpand = true;
                        if (data && data.length > 0) {
                            item.hasChildren = true;
                        } else {
                            item.hasChildren = false;
                        }
                        var ht = [];
                        buildnode(item, ht, deep - 1, path, isend);
                        ht.shift(); ht.pop(); var li = node.parent();
                        li.html(ht.join("")); ht = null; InitEvent(li);
                        bindevent.call(li.find(">div"));
                    });
                }
            } else {
                alert("该节点还没有生成");
            }
        }
        function getck(items, c, fn) { for (var i = 0, l = items.length; i < l; i++) { (items[i].showcheck == true && items[i].checkstate == 1) && c.push(fn(items[i])); if (items[i].ChildNodes != null && items[i].ChildNodes.length > 0) { getck(items[i].ChildNodes, c, fn); } } }
        function getckAuth(items, c, fn) { for (var i = 0, l = items.length; i < l; i++) { (items[i].showcheck == true && items[i].checkstate == 1 || items[i].checkstate == 2) && c.push(fn(items[i])); if (items[i].ChildNodes != null && items[i].ChildNodes.length > 0) { getckAuth(items[i].ChildNodes, c, fn); } } }
        function getCkAndHalfCk(items, c, fn) { for (var i = 0, l = items.length; i < l; i++) { (items[i].showcheck == true && (items[i].checkstate == 1 || items[i].checkstate == 2)) && c.push(fn(items[i])); if (items[i].ChildNodes != null && items[i].ChildNodes.length > 0) { getCkAndHalfCk(items[i].ChildNodes, c, fn); } } }
        me[0].t = {
            getSelectedNodes: function (gethalfchecknode) { var s = []; if (gethalfchecknode) { getCkAndHalfCk(treenodes, s, function (item) { return item; }); } else { getck(treenodes, s, function (item) { return item; }); } return s; },
            getSelectedValues: function () { var s = []; getck(treenodes, s, function (item) { return item.value; }); return s; },
            getSelectedValueAuth: function () { var s = []; getckAuth(treenodes, s, function (item) { return item.value; }); return s; },
            getCurrentItem: function () { return dfop.citem; },
            reflash: function (itemOrItemId) { var id; if (typeof (itemOrItemId) == "string") { id = itemOrItemId; } else { id = itemOrItemId.id; } reflash(id); }
        };
        return me;
    };
    //获取所有选中的节点的Value数组
    $.fn.getTSelectAuth = function () { if (this[0].t) { return this[0].t.getSelectedValueAuth(); } return null; };
    //获取所有选中的节点的Value数组
    $.fn.getTSVs = function () { if (this[0].t) { return this[0].t.getSelectedValues(); } return null; };
    //获取所有选中的节点的Item数组
    $.fn.getTSNs = function (gethalfchecknode) { if (this[0].t) { return this[0].t.getSelectedNodes(gethalfchecknode); } return null; };
    $.fn.getTCT = function () { if (this[0].t) { return this[0].t.getCurrentItem(); } return null; };
    $.fn.reflash = function (ItemOrItemId) { if (this[0].t) { return this[0].t.reflash(ItemOrItemId); } };
})(jQuery);